﻿using System;
using RayDen.Library.Core.Primitives;

namespace RayDen.Library.Components.Surface
{
    [Serializable]
    public class MirrorMaterial : SurfaceBsdf {
        public
            MirrorMaterial(RgbSpectrum refl, bool reflSpecularBounce) {
            Kr = refl;
            reflectionSpecularBounce = reflSpecularBounce;
            }

        public override bool IsDiffuse() { return false; }
        public override bool IsSpecular() { return true; }

        public override void f(ref Vector wo, ref Vector wi, ref Normal N, ref RgbSpectrum in_fs, out RgbSpectrum fs) {
            throw new NotSupportedException("f not supported for Mirror");
        }

        public override float Pdf(ref Vector wo, ref Vector wi, BxDFTypes bxDFType) {
            return 1f;
        }
        public override void Sample_f(ref Vector wo, ref Normal N, ref Normal shadeN, ref RgbSpectrum in_f, float u0, float u1, float u2, ref SurfaceTextureData surfaceData, out BsdfSampleData result) {
            Vector dir = -wo;
            float dp = Normal.Dot(ref shadeN, ref dir);
            result.Lambda = 0f;
            result.Wi = dir - (2f * dp) * shadeN.ToVec();
            result.Type = reflectionSpecularBounce ? BrdfType.Specular : BrdfType.Glossy;
            result.Pdf = 1f;
            result.F = Kr;            
        }

        public RgbSpectrum GetKr() { return Kr; }
        public bool IsSpecularBounce { get { return reflectionSpecularBounce; } }
        private RgbSpectrum Kr;
        private bool reflectionSpecularBounce;

        public override BrdfType Type
        {
            get { return BrdfType.Specular; }
        }
    };
}